package cn.edu.scau.cmi.hombio.service;

import cn.edu.scau.cmi.hombio.dao.PigDAO;
import cn.edu.scau.cmi.hombio.dao.PigstyDAO;
import cn.edu.scau.cmi.hombio.dao.TaskDAO;
import cn.edu.scau.cmi.hombio.dao.TransferDAO;

import cn.edu.scau.cmi.hombio.domain.Pig;
import cn.edu.scau.cmi.hombio.domain.Pigsty;
import cn.edu.scau.cmi.hombio.domain.Task;
import cn.edu.scau.cmi.hombio.domain.Transfer;

import java.util.List;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;

import org.springframework.transaction.annotation.Transactional;

/**
 * Spring service that handles CRUD requests for Transfer entities
 * 
 */

@Service("TransferService")

@Transactional
public class TransferServiceImpl implements TransferService {

	/**
	 * DAO injected by Spring that manages Pig entities
	 * 
	 */
	@Autowired
	private PigDAO pigDAO;

	/**
	 * DAO injected by Spring that manages Pigsty entities
	 * 
	 */
	@Autowired
	private PigstyDAO pigstyDAO;

	/**
	 * DAO injected by Spring that manages Task entities
	 * 
	 */
	@Autowired
	private TaskDAO taskDAO;

	/**
	 * DAO injected by Spring that manages Transfer entities
	 * 
	 */
	@Autowired
	private TransferDAO transferDAO;

	/**
	 * Instantiates a new TransferServiceImpl.
	 *
	 */
	public TransferServiceImpl() {
	}

	/**
	 * Save an existing Transfer entity
	 * 
	 */
	@Transactional
	public void saveTransfer(Transfer transfer) {
		Transfer existingTransfer = transferDAO.findTransferByPrimaryKey(transfer.getId());

		if (existingTransfer != null) {
			if (existingTransfer != transfer) {
				existingTransfer.setId(transfer.getId());
				existingTransfer.setTime(transfer.getTime());
				existingTransfer.setMemo(transfer.getMemo());
			}
			transfer = transferDAO.store(existingTransfer);
		} else {
			transfer = transferDAO.store(transfer);
		}
		transferDAO.flush();
	}

	/**
	 * Save an existing Pig entity
	 * 
	 */
	@Transactional
	public Transfer saveTransferPig(Integer id, Pig related_pig) {
		Transfer transfer = transferDAO.findTransferByPrimaryKey(id, -1, -1);
		Pig existingpig = pigDAO.findPigByPrimaryKey(related_pig.getId());

		// copy into the existing record to preserve existing relationships
		if (existingpig != null) {
			existingpig.setId(related_pig.getId());
			existingpig.setNumber(related_pig.getNumber());
			existingpig.setEarNumber(related_pig.getEarNumber());
			existingpig.setRfid(related_pig.getRfid());
			existingpig.setBirthday(related_pig.getBirthday());
			existingpig.setState(related_pig.getState());
			existingpig.setMemo(related_pig.getMemo());
			related_pig = existingpig;
		}

		transfer.setPig(related_pig);
		related_pig.getTransfers().add(transfer);
		transfer = transferDAO.store(transfer);
		transferDAO.flush();

		related_pig = pigDAO.store(related_pig);
		pigDAO.flush();

		return transfer;
	}

	/**
	 * Save an existing Task entity
	 * 
	 */
	@Transactional
	public Transfer saveTransferTask(Integer id, Task related_task) {
		Transfer transfer = transferDAO.findTransferByPrimaryKey(id, -1, -1);
		Task existingtask = taskDAO.findTaskByPrimaryKey(related_task.getId());

		// copy into the existing record to preserve existing relationships
		if (existingtask != null) {
			existingtask.setId(related_task.getId());
			existingtask.setTaskNumber(related_task.getTaskNumber());
			existingtask.setCreateTime(related_task.getCreateTime());
			existingtask.setStartTime(related_task.getStartTime());
			existingtask.setEndTime(related_task.getEndTime());
			existingtask.setMemo(related_task.getMemo());
			related_task = existingtask;
		}

		transfer.setTask(related_task);
		related_task.getTransfers().add(transfer);
		transfer = transferDAO.store(transfer);
		transferDAO.flush();

		related_task = taskDAO.store(related_task);
		taskDAO.flush();

		return transfer;
	}

	/**
	 * Delete an existing Task entity
	 * 
	 */
	@Transactional
	public Transfer deleteTransferTask(Integer transfer_id, Integer related_task_id) {
		Transfer transfer = transferDAO.findTransferByPrimaryKey(transfer_id, -1, -1);
		Task related_task = taskDAO.findTaskByPrimaryKey(related_task_id, -1, -1);

		transfer.setTask(null);
		related_task.getTransfers().remove(transfer);
		transfer = transferDAO.store(transfer);
		transferDAO.flush();

		related_task = taskDAO.store(related_task);
		taskDAO.flush();

		taskDAO.remove(related_task);
		taskDAO.flush();

		return transfer;
	}

	/**
	 * Delete an existing Transfer entity
	 * 
	 */
	@Transactional
	public void deleteTransfer(Transfer transfer) {
		transferDAO.remove(transfer);
		transferDAO.flush();
	}

	/**
	 */
	@Transactional
	public Transfer findTransferByPrimaryKey(Integer id) {
		return transferDAO.findTransferByPrimaryKey(id);
	}

	/**
	 * Delete an existing Pigsty entity
	 * 
	 */
	@Transactional
	public Transfer deleteTransferPigsty(Integer transfer_id, Integer related_pigsty_id) {
		Transfer transfer = transferDAO.findTransferByPrimaryKey(transfer_id, -1, -1);
		Pigsty related_pigsty = pigstyDAO.findPigstyByPrimaryKey(related_pigsty_id, -1, -1);

		transfer.setPigsty(null);
		related_pigsty.getTransfers().remove(transfer);
		transfer = transferDAO.store(transfer);
		transferDAO.flush();

		related_pigsty = pigstyDAO.store(related_pigsty);
		pigstyDAO.flush();

		pigstyDAO.remove(related_pigsty);
		pigstyDAO.flush();

		return transfer;
	}

	/**
	 * Return all Transfer entity
	 * 
	 */
	@Transactional
	public List<Transfer> findAllTransfers(Integer startResult, Integer maxRows) {
		return new java.util.ArrayList<Transfer>(transferDAO.findAllTransfers(startResult, maxRows));
	}

	/**
	 * Save an existing Pigsty entity
	 * 
	 */
	@Transactional
	public Transfer saveTransferPigsty(Integer id, Pigsty related_pigsty) {
		Transfer transfer = transferDAO.findTransferByPrimaryKey(id, -1, -1);
		Pigsty existingpigsty = pigstyDAO.findPigstyByPrimaryKey(related_pigsty.getId());

		// copy into the existing record to preserve existing relationships
		if (existingpigsty != null) {
			existingpigsty.setId(related_pigsty.getId());
			existingpigsty.setNumber(related_pigsty.getNumber());
			existingpigsty.setRfid(related_pigsty.getRfid());
			existingpigsty.setCapacity(related_pigsty.getCapacity());
			existingpigsty.setMemo(related_pigsty.getMemo());
			related_pigsty = existingpigsty;
		}

		transfer.setPigsty(related_pigsty);
		related_pigsty.getTransfers().add(transfer);
		transfer = transferDAO.store(transfer);
		transferDAO.flush();

		related_pigsty = pigstyDAO.store(related_pigsty);
		pigstyDAO.flush();

		return transfer;
	}

	/**
	 * Delete an existing Pig entity
	 * 
	 */
	@Transactional
	public Transfer deleteTransferPig(Integer transfer_id, Integer related_pig_id) {
		Transfer transfer = transferDAO.findTransferByPrimaryKey(transfer_id, -1, -1);
		Pig related_pig = pigDAO.findPigByPrimaryKey(related_pig_id, -1, -1);

		transfer.setPig(null);
		related_pig.getTransfers().remove(transfer);
		transfer = transferDAO.store(transfer);
		transferDAO.flush();

		related_pig = pigDAO.store(related_pig);
		pigDAO.flush();

		pigDAO.remove(related_pig);
		pigDAO.flush();

		return transfer;
	}

	/**
	 * Load an existing Transfer entity
	 * 
	 */
	@Transactional
	public Set<Transfer> loadTransfers() {
		return transferDAO.findAllTransfers();
	}

	/**
	 * Return a count of all Transfer entity
	 * 
	 */
	@Transactional
	public Integer countTransfers() {
		return ((Long) transferDAO.createQuerySingleResult("select count(o) from Transfer o").getSingleResult()).intValue();
	}
}
